//
//  WebUtil.m
//  LOU
//
//  Created by iMacOne on 15/11/9.
//  Copyright © 2015年 UNOHACHA. All rights reserved.
//

#import "WebUtil.h"
#import "DateUtil.h"
#import "DatebaseUtil.h"
#import "ToolUtil.h"
#import "Size.h"
#import "Base64.h"
#import "NSData+Gzip.h"
#import <UIKit/UIKit.h>
#import <SystemConfiguration/SCNetworkReachability.h>
#import "RootViewController.h"
@implementation WebUtil

+ (BOOL)isNet {
    //创建零地址，0.0.0.0的地址表示查询本机的网络连接状态
    struct sockaddr_storage zeroAddress;//IP地址
    bzero(&zeroAddress, sizeof(zeroAddress));//将地址转换为0.0.0.0
    zeroAddress.ss_len = sizeof(zeroAddress);//地址长度
    zeroAddress.ss_family = AF_INET;//地址类型为UDP, TCP, etc.
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    //获得连接的标志
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    //如果不能获取连接标志，则不能连接网络，直接返回
    if (!didRetrieveFlags) {
        return NO;
    }
    //根据获得的连接标志进行判断
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    return (isReachable&&!needsConnection) ? YES : NO;
}
- (id)initWithUpload:(NSString*)_partUrl _control:(RootViewController*)control
{
    self = [super init];
    self.url = _partUrl;
    self.control = control;
    return self;
}
#pragma mark 请求TCK服务器的构造方法
#pragma _partUrl 接口路径，只需要后面一截
#pragma _param 参数，多个参数用&隔开
- (id)initWithTck:(NSString*)_partUrl _param:(NSString*)param _control:(RootViewController*)control
{
    self = [super init];
    self.url = [NSString stringWithFormat:@"%@%@",root_url,_partUrl];
    self.param = ([ToolUtil isBlank:param]?@"":param);
    self.requestServerType = request_server_type_tck;
    self.control = control;
    return self;
    
}
#pragma mark 请求TCK服务器
#pragma _callback 回调函数的block
#pragma loading_type 进度条的类型
#pragma is_backup 是否需要备份数据(一般查询的数据需要备份，提交的数据不需要)
#pragma is_solveFail 调用接口失败时，是否内部处理错误
#pragma _frequency 调用接口的频率(单位：秒)，及时调接口，就传入0
- (void)requestTck:(ResponseCallback)callback loading_type:(LoadingType)loading_type is_backup:(BOOL)is_backup is_solveFail:(BOOL)is_solveFail _frequency:(int)_frequency
{
    self.callback = callback;
    self.loadingType = loading_type;
    self.isBackup = is_backup;
    self.isSolveFail = is_solveFail;
    if ([WebUtil isNet] && [self isRequestTck:_frequency]) {
        [self requestTck1];
        return;
    }
    if (self.isBackup) {
        [self doCallback:net_err_msg];
    }else{
        [self.control prompt:net_err_msg];
        
    }
    
    
}
// 读取本地数据再执行回调函数
- (void)doCallback:(NSString*)errorMsg
{
    NSMutableDictionary *dictionary = [DatebaseUtil getMap:self.url param:self.param];
    if (nil != dictionary) {
        NSData *localData = [[dictionary[@"data"] base64DecodedData] gzipInflate];
        NSDictionary *map = [NSJSONSerialization JSONObjectWithData:localData options:NSJSONReadingAllowFragments error:nil];
        if (nil != self.callback) {
            self.callback([NSMutableDictionary dictionaryWithDictionary:map]);
        }
    } else if (![ToolUtil isBlank:errorMsg]) {
        [self.control prompt:errorMsg];
    }
}
// 确定调用接口
- (void)requestTck1
{
    [self createLoading];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
    [request setTimeoutInterval:request_time_out];
    [request setHTTPMethod:request_post];
    double mathRandom = (float) (1 + arc4random() % 99) / 100 ;
    NSString* chars = ([ToolUtil isBlank:self.param] ? @"" : @"&");
    [NSString stringWithFormat:@"%@%@&mathRandom=%@", self.param, chars, [NSString stringWithFormat:@"%f", mathRandom]];
    [request setHTTPBody:[_param dataUsingEncoding:NSUTF8StringEncoding]];
    NSString *timestamp = [DateUtil formatDateTimeStr:[NSDate date]];
    [request setValue:timestamp forHTTPHeaderField:@"timestamp"];
//    [request setValue:[ToolUtil md5:timestamp] forHTTPHeaderField:@"timestampKey"];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [connection start];
    self.serverData = [NSMutableData data];

    
}
// 是否需要调用线上接口，否则取本地数据
- (BOOL)isRequestTck:(int)frequency
{
    return frequency = 0?NO:YES;
}
- (void)requestUpload:(ResponseCallback)callback _data:(NSData*)_data _fileName:(NSString*)_fileName
{
    if (![WebUtil isNet]) {
        [self.control prompt:net_err_msg];
        return;
    }
    self.callback = callback;
    NSArray * arr = [_fileName componentsSeparatedByString:@"."];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
    [request setHTTPMethod:request_post];
    [request setHTTPBody:_data];
    [request setValue:@"banben" forHTTPHeaderField:@"user-agent"];

    [request setValue:@"Keep-Alive" forHTTPHeaderField:@"connection"];
    [request setValue:@"UTF-8" forHTTPHeaderField:@"Charsert"];
    [request setValue:[NSString stringWithFormat:@"multipart/form-data;file=%@", _fileName] forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@".%@", arr[arr.count - 1]] forHTTPHeaderField:@"ext"];
//    [request setValue:param_ak forHTTPHeaderField:@"ak"];
    NSString *timestamp = [DateUtil formatDateTimeStr:[NSDate date]];
    [request setValue:timestamp forHTTPHeaderField:@"timestamp"];
    double mathRandom = (float) (1 + arc4random() % 99) / 100;
    [request setValue:[NSString stringWithFormat:@"%f", mathRandom] forHTTPHeaderField:@"mathRandom"];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
    
    [connection start];

    self.serverData = [NSMutableData data];

}
// 在视图中间创建进度条
- (void)createLoading {
    if (self.loadingType == loading_type_none) {
        return;
    }
    UIActivityIndicatorView *activity = (UIActivityIndicatorView*) [self.control.view viewWithTag:10000];
    if (nil == activity) {
        activity = [[UIActivityIndicatorView alloc] init];
        [activity setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
        activity.tag = 10000;
        [self.control.view addSubview:activity];
    }
    activity.hidden = NO;
    int x = (WindowWidth - title_height) / 2, y = (WindowHeight - title_height) / 2;
    y = (self.loadingType == loading_type_bottom ? WindowHeight - title_height - bottom_height : y);
    y = (self.loadingType == loading_type_below ? WindowHeight - title_height : y);
    activity.frame = CGRectMake(x, y, title_height, title_height);
    if (!activity.isAnimating) {
        [activity startAnimating];
    }
}
// 关闭进度条
- (void)closeLoading {
    if (self.loadingType == loading_type_none) {
        return;
    }
    UIActivityIndicatorView *activity = (UIActivityIndicatorView*) [self.control.view viewWithTag:10000];
    if (nil != activity && activity.isAnimating) {
        [activity stopAnimating];
        activity.hidden = YES;
    }
}
#pragma mark  代理方法1   接受到服务器的响应，服务器要传数据了，客户端做好接收准备
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    
}
#pragma mark   代理方法2  接收服务器传输的数据，可能会多次执行  对每次传输的数据进行拼接,需要中转数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.serverData appendData:data];
    
}
#pragma mark   代理方法3  接收数据完成，做后续处理
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    if (self.requestServerType == request_server_type_tck) {
//        [self closeLoading];
        NSString *result = [[NSString alloc] initWithData:self.serverData encoding:NSUTF8StringEncoding];
//        if ([ToolUtil isBlank:result] || result.length <= 10) {
//            [DatabaseUtil write:key_login_member value:@""];
//            [Constant bean].loginer = nil;
//            [Member setCookie];
//            [main_control prompt:@"您的账号已在其它设备登录，被迫下线！"];
//            if ([self.control isKindOfClass:[ViewController class]]) {
//                [((ViewController*) self.control) outerShowLogin];
//            } else {
//                ((ViewController*) main_control).isSingleLogin = YES;
//                [control.navigationController popToRootViewControllerAnimated:YES];
//            }
//            return;
//        }
        NSData *data = [[result base64DecodedData] gzipInflate];
        if (nil == data) {
            [self.control prompt:@"请检查自己的网络，是否被代理"];
            return;
        }
        NSDictionary *map = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        if (self.isSolveFail && ![[map objectForKey:@"success"] boolValue]) {
            [self.control prompt:map[@"message"]];
            return;
        }
        if (self.isBackup) {
            [DatebaseUtil add:self.url param:self.param data:result];
        }
        if (nil != self.callback) {
            self.callback([NSMutableDictionary dictionaryWithDictionary:map]);
        }
    } else if (self.requestServerType == request_server_type_upload) {
//        [self closeLoading];
        NSString *result = [[NSString alloc] initWithData:self.serverData encoding:NSUTF8StringEncoding];
        NSData *data = [result dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *map = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        if (![[map objectForKey:@"success"] boolValue]) {
            [self.control prompt:map[@"message"]];
            return;
        }
        if (nil != self.callback) {
            self.callback([NSMutableDictionary dictionaryWithDictionary:map]);
        }
    }
    self.serverData = nil;
}
#pragma mark    代理方法4  f服务器请求失败，原因很多(w网络环境等等);
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSString *errorMsg = ([ToolUtil isBlank:error.localizedDescription] ? load_fail_msg : error.localizedDescription);
//    if (self.requestServerType == request_server_type_tck) {
////        [self closeLoading];
//        if (self.isBackup) {
//            [self doCallback:errorMsg];
//        } else {
//            [self.control prompt:errorMsg];//本地化的错误信息描述。
//        }
//    } else if (self.requestServerType == request_server_type_upload) {
//        [self closeLoading];
//        [self.control prompt:errorMsg];
//    }
}
#pragma mark    代理方法5  向服务器发送数据，次方法仅适用于post，尤其上传文件。
/*
 第一个参数是连接，第二个参数是发送的数据体，第三个表示整体要写的数据，第四个是表示预期要写的数据。服务器通过这些值知道这次传了多少，已经传了多少，预期总共要穿多少
 */
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
    
}

@end
